<!DOCTYPE>
<!--解决idea thymeleaf 表达式模板报红波浪线-->
<!--suppress ALL -->
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>WebRTC + WebSocket</title>
    <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no">
    <style>
        html, body {
            margin: 0;
            padding: 0;
        }
        .hide {
            display: none !important;
        }

        #main {
            /*position: absolute;*/
            /*width: 360px;*/
            /*height: 700px;*/
        }

        #localVideo {
            position: absolute;
            background: #757474;
            top: 10px;
            right: 10px;
            width: 100px;
            height: 150px;
            z-index: 3;
        }

        #remoteVideo {
            position: absolute;
            top: 0px;
            left: 0px;
            width: 100%;
            height: 100%;
            z-index: 3;
        }

        #buttons {
            z-index: 4;
            bottom: 20px;
            left: 15%;
            position: absolute;
        }

        #toUser {
            border: 1px solid #ccc;
            padding: 7px 0px;
            border-radius: 5px;
            padding-left: 5px;
            margin-bottom: 15px;
            margin-left: 50px;
        }

        #toUser:focus {
            border-color: #66afe9;
            outline: 0;
            -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6);
            box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6)
        }

        #call {
            width: 70px;
            height: 35px;
            background-color: #00BB00;
            border: none;
            margin-right: 25px;
            color: white;
            border-radius: 5px;
        }

        #audio-call {
            width: 70px;
            height: 35px;
            background-color: #0879ea;
            border: none;
            margin-right: 25px;
            color: white;
            border-radius: 5px;
        }

        #hangup {
            width: 70px;
            height: 35px;
            background-color: #FF5151;
            border: none;
            color: white;
            border-radius: 5px;
        }
        .avatar-bg{
            position: relative;
            width: 80px;
            height: 80px;
            left: 38%;
            top: 18%;
            z-index: 2;
        }
        .avatar{
            width: 80px;
            height: 80px;
            border-radius: 10px;
        }
        .container-pc{
            width: 480px !important;
            height: 360px !important;
        }
        .container{
            position: absolute;
            width: 360px;
            height: 700px;
            background-image: url(./img/avatar-b.jpg);
            background-position: center;
            background-size: cover;
            overflow: hidden;
            z-index: 1;
        }
        .frosted-glass{
            position: absolute;
            width: 100%;
            height: 100%;
            z-index: 2;
            background: rgb(0 0 0 / 51%);
            -webkit-backdrop-filter: blur(45px);
            backdrop-filter: blur(45px);
        }
    </style>
</head>
<body>
<div id="main">
    <div id="container" class='container'>
        <div class='frosted-glass'></div>
        <div class="avatar-bg"><img src="./img/avatar-b.jpg" class="avatar"></div>
        <video id="remoteVideo" playsinline autoplay></video>
        <video id="localVideo" class="hide" playsinline autoplay muted></video>

        <div id="buttons">
            <input id="toUser" placeholder="输入在线好友账号"/><br/>
            <button id="call">视频通话</button>
            <button id="audio-call">语音通话</button>
            <button id="hangup">挂断</button>
        </div>
    </div>
</div>
</body>
<script src="./js/webrtc-util.js" type="text/javascript"></script>
<script type="text/javascript" th:inline="javascript">
    let username = location.search.replace("?", "");
    let websocket = null;
    if (!username){
        username = prompt("请输入用户名或在地址后加用户名index.html?张三");
    }
    if (!mobile){
        document.getElementById('container').classList.add('container-pc');
    }
    WebSocketInit();
    ButtonFunInit();

    /* WebSocket */
    function WebSocketInit() {
        //判断当前浏览器是否支持WebSocket
        if ('WebSocket' in window) {
            websocket = new WebSocket("wss://172.16.85.134:8080/webrtc/" + username);
        } else {
            alert("当前浏览器不支持WebSocket！");
        }

        //连接发生错误的回调方法
        websocket.onerror = function (e) {
            alert("WebSocket连接发生错误！username:",username);
        };

        //连接关闭的回调方法
        websocket.onclose = function () {
            console.error("WebSocket连接关闭,username:",username);
        };

        //连接成功建立的回调方法
        websocket.onopen = function () {
            console.log("WebSocket连接成功,username:",username);
        };

        //接收到消息的回调方法
        websocket.onmessage = async function (event) {
            // console.log('收到消息：', event.data);
            let {type, fromUser, msg, desc, candidate, callType} = JSON.parse(event.data);
            console.log('type:', type);

            if (type === 'hangup') {
                console.log(msg);
                hangup();
            } else if (type === 'call_start') {
                let msg = "0"
                if (confirm(fromUser + "发起视频通话，确定接听吗") == true) {
                    document.getElementById('toUser').value = fromUser;
                    let toUser = fromUser;
                    WebRTCInit();
                    msg = "1"
                }
                websocket.send(JSON.stringify({
                    type: "call_back",
                    toUser: fromUser,
                    fromUser: username,
                    callType: callType,
                    msg: msg
                }));
            } else if (type === 'call_back') {
                if (msg === "1") {
                    console.log(document.getElementById('toUser').value + "同意视频通话");
                    // 先打开视频流, 在创建用于 offer 的 SDP 对象
                    openLocalMedia(callType, stream => {
                        // 显示本地视频流
                        localVideo.srcObject = stream;
                        if (callType === 'video') {
                            localVideo.classList.remove('hide');
                        }
                        createOffer(desc => {
                            console.log('创建并发送 offer,offer:', desc);
                            let msgObj = {
                                type: 'offer',
                                fromUser: username,
                                toUser: document.getElementById('toUser').value,
                                callType: callType,
                                desc: desc
                            }
                            websocket.send(JSON.stringify(msgObj));
                        });
                    });

                } else if (msg === "0") {
                    alert(document.getElementById('toUser').value + "拒绝视频通话");
                    document.getElementById('hangup').click();
                } else {
                    alert(msg);
                    hangup();
                }
            } else if (type === 'offer') {
                console.log('收到offer');
                //先保存收到的 offer
                saveSdp(desc, () => {
                    console.log('offer 保存成功');

                    //再打开音视频流
                    openLocalMedia(mediaConstraints, stream => {
                        localVideo.srcObject = stream;
                        if (callType === 'video') {
                            localVideo.classList.remove('hide');
                        }
                        //最后创建用于 answer 的 SDP 对象
                        createAnswer(desc => {
                            console.log('创建并发送 answer');
                            let msgObj = {
                                type: 'answer',
                                fromUser: username,
                                toUser: document.getElementById('toUser').value,
                                callType: callType,
                                desc: desc
                            }
                            websocket.send(JSON.stringify(msgObj));
                        });
                    });
                });
            } else if (type === 'answer') {
                console.log('收到 answer');
                saveSdp(desc, () => console.log('answer 保存成功'));
            } else if (type === 'candidate') {
                //用于交换 candidate
                saveIceCandidate(candidate);
            }
        }
    }

    /* WebRTC */
    function WebRTCInit() {
        // 1、创建端点
        createPeerConnection();
        // 2、绑定 收集 candidate 的回调
        bindOnIceCandidate(candidate =>
            websocket.send(JSON.stringify({
                type: 'candidate',
                toUser: document.getElementById('toUser').value,
                fromUser: username,
                candidate: candidate
            })));
        // 3、绑定 获得 远程视频流 的回调
        bindOnTrack(stream => {
            console.log('获得远程视频流');
            //显示 远程视频流
            remoteVideo.srcObject = stream;
        });
    }

    /* 按钮事件 */
    function ButtonFunInit() {
        //视频通话
        document.getElementById('call').onclick = function (e) {
            document.getElementById('toUser').style.visibility = 'hidden';
            let toUser = document.getElementById('toUser').value;
            if (!toUser) {
                alert("请先指定好友账号，再发起视频通话！");
                return;
            }

            if (rtcPeerConnection == null) {
                WebRTCInit();
            }

            websocket.send(JSON.stringify({
                type: "call_start",
                fromUser: username,
                toUser: toUser,
                callType: "video"
            }));
        }
        //语音通话
        document.getElementById('audio-call').onclick = function (e) {
            document.getElementById('toUser').style.visibility = 'hidden';
            let toUser = document.getElementById('toUser').value;
            if (!toUser) {
                alert("请先指定好友账号，再发起语音通话！");
                return;
            }

            if (rtcPeerConnection == null) {
                WebRTCInit();
            }

            websocket.send(JSON.stringify({
                type: "call_start",
                fromUser: username,
                toUser: toUser,
                callType: "audio"
            }));
        }

        //挂断
        document.getElementById('hangup').onclick = function (e) {
            console.log('通知对方关闭视频流');
            //挂断同时，通知对方
            websocket.send(JSON.stringify({
                type: "hangup",
                fromUser: username,
                toUser: document.getElementById('toUser').value,
            }));
            //挂断
            hangup();
        }
    }
</script>


<!--手机端查看浏览器控制台-->
<script src="./js/jsdelivr-eruda.js"></script>
<script>
    eruda.init();
    console.log('控制台打印信息');
</script>
</html>